#include <QCoreApplication>
#include <QCommandLineParser>
#include <QCommandLineOption>
#include <QHostAddress>
#include <QTimer>
#include <QSignalMapper>
#include <QTextStream>
#include <QDebug>
#include <iostream>

#include "transferskt.h"
#include "setting.h"

class SokitCLI : public QCoreApplication
{
    Q_OBJECT

public:
    SokitCLI(int& argc, char** argv) : QCoreApplication(argc, argv)
    {
        setApplicationName("sokit-cli");
        setApplicationVersion("1.3.1");
    }

    bool parseArguments()
    {
        QCommandLineParser parser;
        parser.setApplicationDescription("Sokit CLI - High-performance TCP/UDP data transfer tool");
        parser.addHelpOption();
        parser.addVersionOption();

        // 添加命令行选项
        QCommandLineOption tcpOption(QStringList() << "t" << "tcp", "Use TCP protocol");
        QCommandLineOption udpOption(QStringList() << "u" << "udp", "Use UDP protocol");
        QCommandLineOption verboseOption(QStringList() << "v" << "verbose", "Verbose output");
        QCommandLineOption quietOption(QStringList() << "q" << "quiet", "Quiet mode (minimal output)");
        QCommandLineOption statsOption(QStringList() << "s" << "stats", "Show transfer statistics");
        QCommandLineOption timeoutOption(QStringList() << "timeout", "Connection timeout in seconds", "30", "30");

        parser.addOption(tcpOption);
        parser.addOption(udpOption);
        parser.addOption(verboseOption);
        parser.addOption(quietOption);
        parser.addOption(statsOption);
        parser.addOption(timeoutOption);

        // 添加位置参数
        parser.addPositionalArgument("source", "Source address:port (e.g., 127.0.0.1:8080)");
        parser.addPositionalArgument("destination", "Destination address:port (e.g., 192.168.1.100:9090)");

        parser.process(*this);

        // 检查参数
        if (parser.positionalArguments().size() != 2) {
            std::cerr << "Error: Source and destination addresses are required." << std::endl;
            std::cerr << "Usage: sokit-cli [options] <source> <destination>" << std::endl;
            std::cerr << "Example: sokit-cli -t 127.0.0.1:8080 192.168.1.100:9090" << std::endl;
            return false;
        }

        // 解析地址
        if (!parseAddress(parser.positionalArguments().at(0), m_sourceAddr, m_sourcePort)) {
            std::cerr << "Error: Invalid source address format." << std::endl;
            return false;
        }

        if (!parseAddress(parser.positionalArguments().at(1), m_destAddr, m_destPort)) {
            std::cerr << "Error: Invalid destination address format." << std::endl;
            return false;
        }

        // 设置选项
        m_useTcp = parser.isSet(tcpOption);
        m_useUdp = parser.isSet(udpOption);
        m_verbose = parser.isSet(verboseOption);
        m_quiet = parser.isSet(quietOption);
        m_showStats = parser.isSet(statsOption);
        m_timeout = parser.value(timeoutOption).toInt();

        // 检查协议选项
        if (!m_useTcp && !m_useUdp) {
            std::cerr << "Error: Must specify either -t (TCP) or -u (UDP) protocol." << std::endl;
            return false;
        }

        if (m_useTcp && m_useUdp) {
            std::cerr << "Error: Cannot use both TCP and UDP protocols simultaneously." << std::endl;
            return false;
        }

        return true;
    }

    bool startTransfer()
    {
        // 创建传输对象
        if (m_useTcp) {
            m_transfer = new TransferSktTcp(this);
        } else {
            m_transfer = new TransferSktUdp(this);
        }

        // 连接信号
        connect(m_transfer, &TransferSkt::message, this, &SokitCLI::onMessage);
        connect(m_transfer, &TransferSkt::connOpen, this, &SokitCLI::onConnOpen);
        connect(m_transfer, &TransferSkt::connClose, this, &SokitCLI::onConnClose);
        connect(m_transfer, &TransferSkt::countRecv, this, &SokitCLI::onCountRecv);
        connect(m_transfer, &TransferSkt::countSend, this, &SokitCLI::onCountSend);
        connect(m_transfer, &TransferSkt::stopped, this, &SokitCLI::onStopped);

        // 启动传输
        if (!m_transfer->start(m_sourceAddr, m_sourcePort, m_destAddr, m_destPort)) {
            std::cerr << "Error: Failed to start transfer server." << std::endl;
            return false;
        }

        if (!m_quiet) {
            std::cout << "Sokit CLI started successfully!" << std::endl;
            std::cout << "Protocol: " << (m_useTcp ? "TCP" : "UDP") << std::endl;
            std::cout << "Source: " << m_sourceAddr.toString().toStdString() << ":" << m_sourcePort << std::endl;
            std::cout << "Destination: " << m_destAddr.toString().toStdString() << ":" << m_destPort << std::endl;
            std::cout << "Press Ctrl+C to stop..." << std::endl;
        }

        // 设置统计定时器
        if (m_showStats) {
            m_statsTimer = new QTimer(this);
            connect(m_statsTimer, &QTimer::timeout, this, &SokitCLI::showStats);
            m_statsTimer->start(5000); // 每5秒显示一次统计
        }

        return true;
    }

private slots:
    void onMessage(const QString& msg)
    {
        if (!m_quiet) {
            std::cout << "[INFO] " << msg.toStdString() << std::endl;
        }
    }

    void onConnOpen(const QString& key)
    {
        if (m_verbose) {
            std::cout << "[CONN] Connection opened: " << key.toStdString() << std::endl;
        }
    }

    void onConnClose(const QString& key)
    {
        if (m_verbose) {
            std::cout << "[CONN] Connection closed: " << key.toStdString() << std::endl;
        }
    }

    void onCountRecv(qint32 bytes)
    {
        m_bytesReceived += bytes;
        if (m_verbose) {
            std::cout << "[RECV] " << bytes << " bytes received" << std::endl;
        }
    }

    void onCountSend(qint32 bytes)
    {
        m_bytesSent += bytes;
        if (m_verbose) {
            std::cout << "[SEND] " << bytes << " bytes sent" << std::endl;
        }
    }

    void onStopped()
    {
        std::cout << "Transfer stopped." << std::endl;
        quit();
    }

    void showStats()
    {
        std::cout << "=== Transfer Statistics ===" << std::endl;
        std::cout << "Bytes Received: " << m_bytesReceived << std::endl;
        std::cout << "Bytes Sent: " << m_bytesSent << std::endl;
        std::cout << "Total: " << (m_bytesReceived + m_bytesSent) << " bytes" << std::endl;
        std::cout << "========================" << std::endl;
    }

private:
    bool parseAddress(const QString& addrStr, QHostAddress& addr, quint16& port)
    {
        QStringList parts = addrStr.split(':');
        if (parts.size() != 2) {
            return false;
        }

        if (!addr.setAddress(parts[0])) {
            return false;
        }

        bool ok;
        port = parts[1].toUShort(&ok);
        return ok && port > 0;
    }

private:
    QHostAddress m_sourceAddr;
    QHostAddress m_destAddr;
    quint16 m_sourcePort;
    quint16 m_destPort;
    bool m_useTcp;
    bool m_useUdp;
    bool m_verbose;
    bool m_quiet;
    bool m_showStats;
    int m_timeout;
    
    TransferSkt* m_transfer;
    QTimer* m_statsTimer;
    qint64 m_bytesReceived;
    qint64 m_bytesSent;
};

int main(int argc, char *argv[])
{
    SokitCLI app(argc, argv);

    if (!app.parseArguments()) {
        return 1;
    }

    if (!app.startTransfer()) {
        return 1;
    }

    return app.exec();
}

#include "main.moc" 